package cn.yusei.teamTribe.spider;

import java.io.IOException;
import java.text.ParseException;
import java.util.concurrent.TimeUnit;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import cn.yusei.teamTribe.constant.Gender;
import cn.yusei.teamTribe.constant.SchoolCode;
import cn.yusei.teamTribe.entity.Student;
import cn.yusei.teamTribe.entity.ValidateCode;
import cn.yusei.teamTribe.spider.exception.AccessException;
import cn.yusei.teamTribe.spider.exception.UnknownException;
import cn.yusei.teamTribe.spider.exception.ValidateCodeErrorException;
import cn.yusei.teamTribe.util.EncryptionUtil;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class CsustSpider extends AbstractSpider{

	private static final String BASE_URL = "http://xk.csust.edu.cn/";
	private static final String LOGIN_URL = "_data/index_LOGIN.aspx";
	private static final String VALIDATE_URL = "sys/ValidateCode.aspx";
	private static final String MESSAGE_URL = "xsxj/Stu_MyInfo_RPT.aspx";
	
	public static final int SUCCESS = 0;
	public static final int VALIDATECODE_ERROR = 1;
	public static final int ACCESS_ERROR = 2;
	public static final int OTHER_ERROR = 3;
	
	private static String __VIEWSTATE = "dDw4ODEwMTkyNTY7Oz6u+vsnS0fhmG7O5JLDBmk//LdovQ==";
	private static String __VIEWSTATEGENERATOR = "CAA0A5A7";
	private static String pcInfo = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36undefined5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36 SN:NULL";
	private static String typeName = "%D1%A7%C9%FA";
	private static String Sel_Type = "STU";
	private static String txt_pewerwedsdfsdff = "";
	private static String txt_sdertfgsadscxcadsads = "";
	private static String sbtState = "";
	
	private  static String md5Password(String username, String md5Password)
	{
		String temp = username + md5Password.substring(0, 30).toUpperCase() + "10536";
		String result = EncryptionUtil.getEncryptedString(temp).substring(0, 30).toUpperCase();
		return result;
	}
	
	private static String md5ValidateCode(String validateCode)
	{
		String temp = EncryptionUtil.getEncryptedString(validateCode.toUpperCase()).substring(0, 30).toUpperCase() + "10536";
		String result = EncryptionUtil.getEncryptedString(temp).substring(0, 30).toUpperCase();
		return result;
	}
	
	public ValidateCode getValidateCode() throws IOException
	{
		Response response = new OkHttpClient.Builder()
				.connectTimeout(connectionTimeoutSeconds, TimeUnit.SECONDS)
				.build()
		.newCall
		(
				new Request.Builder()
				.url(BASE_URL + VALIDATE_URL)
				.addHeader("Referer", BASE_URL + LOGIN_URL)
				.build()
		).execute();
		String setCookie = response.header("Set-Cookie");
		String sessionId = setCookie.substring(setCookie.indexOf('=') + 1, setCookie.indexOf(';'));
		return new ValidateCode(sessionId, response.body().byteStream());
	}
	
	@Override
	 public Student getStudent(String username, String md5Password, String validateCode, String sessionId)
			 throws IOException, ParseException, AccessException, ValidateCodeErrorException, UnknownException
	{
		switch (login(username, md5Password, validateCode, sessionId))
		{
			case ACCESS_ERROR : throw new AccessException();
			case VALIDATECODE_ERROR : throw new ValidateCodeErrorException();
			case OTHER_ERROR : throw new UnknownException();
		}
	 	Response response = new OkHttpClient.Builder()
	 			.connectTimeout(connectionTimeoutSeconds, TimeUnit.SECONDS)
	 			.build()
	 	.newCall
		(
			new Request.Builder()
				.url(BASE_URL + MESSAGE_URL)
				.addHeader("Referer", BASE_URL + LOGIN_URL)
				.addHeader("Cookie", "ASP.NET_SessionId=" + sessionId)
				.build()
		).execute();
		Document doc = Jsoup.parse(response.body().string());
		Elements elements = doc.select("tr");
		Student student = new Student();
		int elementNum = elements.size();
		for(int i=0; i<elementNum; i++)
		{
			Elements tr = elements.get(i).select("td");
			int trNum = tr.size();
			for(int j=0; j<trNum; j++)
			{
				switch(tr.get(j).text())
				{
					case "学    号":
						student.setNo(tr.get(j + 1).text());
						break;
					case "姓    名":
						student.setName(tr.get(j + 1).text());
						break;
					case "性    别":
						student.setGender(tr.get(j + 1).text().equals("男") ? Gender.BOY : Gender.GIRL);
						break;
					case "出生日期":
						student.setBirthday(tr.get(j + 1).text());
						break;
					case "入学年份":
						student.setGrade(Integer.parseInt(tr.get(j + 1).text()));
						break;
					case "院(系)/部":
						student.setAcademy(tr.get(j + 1).text());
						break;
					case "专业":
						student.setMajor(tr.get(j + 1).text());
						break;
					case "行政班级":
						String classIndex = tr.get(j + 1).text();
						classIndex = classIndex.substring(classIndex.length() - 1);
						student.setCla(Integer.parseInt(classIndex));
						break;
					}
				}
			}
			student.setSchoolId(SchoolCode.CSUST);
			return student;
		}
	
	/**
	 * 
	 * @param username
	 * @param md5Password
	 * @param validateCode
	 * @param sessionId
	 * @return	
	 * @throws IOException
	 */
	private int login(String username, String md5Password, String validateCode, String sessionId) throws IOException
	{
		String dsdsdsdsdxcxdfgfg = md5Password(username, md5Password);
		String fgfggfdgtyuuyyuuckjg = md5ValidateCode(validateCode);
		String txt_asmcdefsddsd = username;
		
		OkHttpClient client = new OkHttpClient.Builder()
				.connectTimeout(connectionTimeoutSeconds, TimeUnit.SECONDS)
				.build();
		FormBody body = new FormBody.Builder()
				.add("dsdsdsdsdxcxdfgfg", dsdsdsdsdxcxdfgfg)
				.add("fgfggfdgtyuuyyuuckjg", fgfggfdgtyuuyyuuckjg)
				.add("txt_asmcdefsddsd", txt_asmcdefsddsd)
				.add("__VIEWSTATE", __VIEWSTATE)
				.add("__VIEWSTATEGENERATOR", __VIEWSTATEGENERATOR)
				.add("pcInfo", pcInfo)
				.add("Sel_Type", Sel_Type)
				.add("txt_pewerwedsdfsdff", txt_pewerwedsdfsdff)
				.add("txt_sdertfgsadscxcadsads", txt_sdertfgsadscxcadsads)
				.add("sbtState", sbtState)
				.addEncoded("typeName", typeName)
				.build();
		Request request = new Request.Builder()
				.post(body)
				.header("Referer", BASE_URL + LOGIN_URL)
				.header("Cookie", "ASP.NET_SessionId=" + sessionId)
				.url(BASE_URL + LOGIN_URL)
				.build();
		Response response = client.newCall(request).execute();
		String responseStr = response.body().string();
		response.body().close();
		if(responseStr.contains("正在加载"))
			return SUCCESS;
		if(responseStr.contains("验证码错误"))
			return VALIDATECODE_ERROR;
		if(responseStr.contains("帐号或密码不正确"))
			return ACCESS_ERROR;
		return OTHER_ERROR;
	}
}
